import fetch from 'node-fetch'
import { createRequire } from 'module'
import { Config } from '../components/index.js'
const require = createRequire(import.meta.url)
const fs = require('fs')
const { exec } = require('child_process')
// b站cookie用于1080p视频及以上
const path = process.cwd() + '/plugins/xiaoyue-plugin/resources/xyplus/bili'

let cookie = JSON.parse(await redis.get('xiaoyue:bcookie'))

async function init () {
  createDataDir(process.cwd() + '/plugins/xiaoyue-plugin/resources/xyplus/')
}

async function createDataDir (dir) {
  if (!fs.existsSync(dir)) { fs.mkdirSync(dir) }
  if (!fs.existsSync(path)) { fs.mkdirSync(path) }
}

init()

export class bv extends plugin {
  constructor (e) {
    super({
      /** 功能名称 */
      name: '小月b站功能',
      dsc: '小月b站功能',
      event: 'message',
      priority: 1045,
      rule: [{
        reg: '',
        desc: 'b站视频解析，检测到链接卡片自动解析',
        fnc: 'bili',
        log: false
      }, {
        reg: '#设置b站ck',
        desc: '设置b站cookie用于1080p视频及以上',
        fnc: 'setBcookie'

      }
      ]
    })
  }

  async bili () {
    let config = Config.xyss
    if (!config.bljx) return false
    let that = this
    let msg = that.e.msg
    let ck = cookie
    let urllist = ['b23.tv', 'm.bilibili.com', 'www.bilibili.com']
    let reg2 = new RegExp(`${urllist[0]}|${urllist[1]}|${urllist[2]}`)
    if (!msg && that.e.raw_message != '[json消息]' && that.e.raw_message != '[xml消息]') {
      return false
    }
    if (that.e.raw_message == '[json消息]') {
      let json = JSON.parse(that.e.message[0].data)
      msg = msg || json.meta.detail_1?.qqdocurl || json.meta.news?.jumpUrl
    }
    if (that.e.raw_message == '[xml消息]') {
      logger.warn(msg.toString())
    }
    if (!msg.match(reg2)) {
      return false
    }

    const regurl = /(https?|http|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g

    let url = msg.match(regurl)[0]// 'https://www.bilibili.com/video/BV19y4y1f7Rf/?spm_id_from=autoNext&vd_source=478dcc286bfddccd0df1500770bef5fc' //that.e.msg
    let bilireg = /(BV.*?).{10}/
    let bv = url.match(bilireg)
    let videoInfo = {}
    if (bv) {
      // 存在bv长链接
      bv = bv[0]
    } else {
      // 不存在短链接
      await fetch(url).then(res => {
        bv = res.url.match(bilireg)[0]
      })
    }
    videoInfo = (await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${bv}`).then(res => res.json()))?.data || {}

    if (videoInfo.duration >= 480 && videoInfo.duration < 900) {
      that.e.reply('检测到长视频，已降低视频质量以提高反应速度')
    }
    let videourl, audioUrl

    if (videoInfo.duration >= 900) {
      that.e.reply('检测到超长视频，已将视频质量调整到最低以提高反应速度')
      let videoPath = path + '/bibilli.mp4'
      await fetch(`https://api.bilibili.com/x/player/playurl?bvid=${videoInfo.bvid}&cid=${videoInfo.cid}&qn=120`).then(async res => {
        let json = await res.json()
        let data = json.data
        videourl = data.durl[0].backup_url[0] || data.durl[0].backup_url[1] || data.durl[0].url
      })

      await downBiliFile(videourl, videoPath, () => {
        this.e.reply(segment.video(videoPath))
        fs.unlink(videoPath, f => f)
      })
    } else {
      await fetch(`https://www.bilibili.com/video/${bv}`, {
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69',
          'referer': 'https://www.bilibili.com',
          cookie
        }
      }).then(async res => {
        let html = await res.text()
        let data = html.match(/<script>window\.__playinfo__=({.*})<\/script><script>/)?.[1]
        data = JSON.parse(data)
        videourl = data.data.dash.video[0]?.baseUrl ?? data.data.dash?.video[0]?.backupUrl[0]
        audioUrl = data.data.dash.audio[0]?.baseUrl ?? data.data.dash?.audio[0]?.backupUrl[0]
      })
      let videoPath = path + '/bibilli.mp4'
      let audioPath = path + '/bibilli.mp3'
      await downBiliFile(videourl, videoPath)
      await downBiliFile(audioUrl, audioPath)
      let resultPath = path + '/result.mp4'
      let flag = 0
      exec(`ffmpeg -y -i ${videoPath} -i ${audioPath} -c copy ${resultPath}`, async function (err) {
        if (!err) {
          that.e.reply(segment.video(resultPath))
          flag = 1
        } else {
          logger.warn(err)
        }
      })

      return true
    }
  }

  async setBcookie () {
    if (this.e.isGroup) {
      return this.reply('请私聊发送你的b站cookie!')
    }
    this.reply('请发送你的b站cookie!')
    this.setContext('getBcookie', false, 120)
  }

  async getBcookie () {
    let trueCk = true
    let ck = this.e.msg
    let cklist = ['bili_jct', 'DedeUserID', 'DedeUserID__ckMd5']
    cklist.forEach(item => {
      if (!ck.includes(item)) {
        trueCk = false
      }
    })
    if (!trueCk) {
      return this.reply('cookie格式错误！')
    } else {
      redis.set('xiaoyue:bcookie', JSON.stringify(ck))
      cookie = ck
      this.reply('cookie设置完毕！')
      this.finish('getBcookie')
    }
  }
}
function computew (num) {
  return num >= 10000 ? (num / 10000).toFixed(1) + 'w' : num
}

async function downBiliFile (url, path, suc = () => {
}) {
  await fetch(url, {
    headers: {
      referer: 'https://www.bilibili.com/'
    }

  }).then(async res => {
    let rep = await res.arrayBuffer()
    fs.writeFile(path, Buffer.from(rep), 'binary', function (err) {
      if (!err) {
        suc()
      }
    })
  })
}
function addnull (str, target) {
  let idx = str.indexOf(target)
  console.log(idx)
  if (idx == 14) {
    return str
  } else if (idx < 14) {
    let arr = Array.from(str)
    let index = 14 - idx
    for (let i = 0; i < index; i++) {
      arr.splice(idx, 0, '  ')
    }
    return arr.join('')
  }
}
